package at.fhooe.stefanirndorfer.quadtree;

import static org.lwjgl.opengl.GL11.GL_LINE_LOOP;
import static org.lwjgl.opengl.GL11.GL_QUADS;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glColor3f;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glVertex2d;

import java.util.Random;

import org.lwjgl.input.Mouse;

import at.fhooe.stefanirndorfer.entity.Entity;
import at.fhooe.stefanirndorfer.game.Game;
import at.fhooe.stefanirndorfer.input.MouseInputListener;
import at.fhooe.stefanirndorfer.labeling.Region;

public class QuadTreeNode extends Entity implements MouseInputListener{

	private double size;
	private double[] center;
	private QuadTreeNode[] childNodes;
	private QuadTreeNode father;
	private boolean isWall;
	private Region label;
	private short sonType;
	private float[] leafColor;
	private boolean showLeafColor;
	private boolean selected;
	private boolean isInBounds;

	
	public QuadTreeNode(double size2, double[] center, QuadTreeNode father, short sonType) {
		super(size2, size2, center[0]-size2/2, center[1]+size2/2);
		this.size = size2;
		this.center = center;
		this.father = father;
		childNodes = new QuadTreeNode[4]; //child nodes in order: NW, NE, SE, SW
		isWall = false;
		label = null;
		this.sonType = sonType;
		
		leafColor = randomizeColor();
		showLeafColor = true;
		
		selected = false;
		isInBounds = false;
		setUpMouseInputListener();
	}
	

	private float[] randomizeColor() {
		this.leafColor = new float[3];
		Random rand = new Random();
		for (int i = 0; i < leafColor.length; i++) {
			leafColor[i] = rand.nextFloat();
		}
		return leafColor;
	}
	
	
	//////////////////////////////////////////////////
	// Getters and Setters
	//////////////////////////////////////////////////



	public double getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public double[] getCenter() {
		return center;
	}

	public void setCenter(double[] center) {
		this.center = center;
	}

	public QuadTreeNode[] getChildNodes() {
		return childNodes;
	}

	public void setChildNodes(QuadTreeNode[] childNodes) {
		this.childNodes = childNodes;
		tearDownMouseInputListener(this);
	}
	
	public boolean isWall() {
		return isWall;
	}
	
	public void setIsWall(boolean isWall) {
		this.isWall = isWall;
	}
	
	public short getSontype() {
		return sonType;
	}
	

	//////////////////////////////////////////////////
	// Overridden Methods
	//////////////////////////////////////////////////
	

	public QuadTreeNode getFather() {
		return father;
	}

	public void setFather(QuadTreeNode father) {
		this.father = father;
	}

	

	@Override
	public double[] getPosition() {
		
		return null;
	}


	@Override
	public void render() {
		
		
		
		
		if(childNodes[0] == null){
			if(!isWall){
				
				if(label != null && !showLeafColor){
					if(selected){
						glColor3f(1.0f, 0.0f, 0.0f);						
					}else{						
						glColor3f(label.getColor()[0], label.getColor()[1], label.getColor()[2]);
					}
				} else{
					if(showLeafColor){
						glColor3f(leafColor[0], leafColor[1], leafColor[2]);						
					}
				}
				
				glBegin(GL_QUADS);
				glVertex2d(posX, posY);
				glVertex2d(posX, posY - height);
				glVertex2d(posX + width, posY - height);
				glVertex2d(posX + width, posY);
				glEnd();
				
			} 
			
			glColor3f(0.0f, 0.0f, 0.0f);
			glBegin(GL_LINE_LOOP);
			glVertex2d(posX, posY);
			glVertex2d(posX, posY - height);
			glVertex2d(posX + width, posY - height);
			glVertex2d(posX + width, posY);
			glEnd();
		}
	}


	@Override
	public void update(int delta) {
		
	}


	public void setLabel(Region label){
		this.label = label;
		showLeafColor = false;
	}
	
	public Region getLabel(){
		return label;
	}
	

	/**
	 * 
	 * @returns true if a label is already assigned
	 */
	public boolean isLabeled() {
		return label != null;
	}


	public void toggleColors() {
		if(label != null)
		showLeafColor = !showLeafColor;
	}


	@Override
	public void setUpMouseInputListener() {
		Game.getInstance().getInputManager().addMouseListener(this);
	}


	@Override
	public void tearDownMouseInputListener(MouseInputListener il) {
		Game.getInstance().getInputManager().removeMouseListener(this);
		
	}


	@Override
	public void processMouseInput(int x, int y, int dx, int dy) {
		isOnThis(x, y);
		if(isInBounds){
			//Log.info(this, "is in Bounds");
			if(Mouse.isButtonDown(0) && !selected){
				selected = true;
				if(label != null)
				System.out.println(label.toString());
		}else{
			if(!Mouse.isButtonDown(0)){
				selected = false;
				//Log.info(this, "isNotSelected");
			}
		}
		}
		if(selected && !Mouse.isButtonDown(0)){
			selected = !selected;
		}
		
	}


	public boolean destroy() {
		tearDownMouseInputListener(this);
		Game.getInstance().getEntityManager().removeEntity(this);
		return false;
	}

	
	protected void isOnThis(int mX, int mY) {	
		mY = -mY;
		if( mX > posX && mX < posX+width && mY < posY && mY > posY - height ){
			isInBounds = true;
		}else{
			isInBounds = false;
		}
	}

	
}
